#pragma once
#include <iostream>
#include <cassert>
#include <string>
#include <vector>
#include <unordered_map>
#include <fstream>
#include "../common/log.hpp"
#include "../common/util.hpp"
struct Question{
    std::string number;//题号
    std::string title;//题目标题
    std::string star;//困难系数
    int cpu_limit;
    int mem_limit;
    std::string desc;//题目描述
    std::string code;// 题目预设给用户在线编辑器的代码
    std::string test;  // 题目的测试用例，需要和code拼接，形成完整代码

};

//加载题目文件
class Model{
    private:
        std::unordered_map<std::string,Question> question_map;//题号和题目对照
        const std::string _question_path = "/home/dyx/Oline_judge/oj_server/questions/";//所有题目的大路径
        //                                  /home/dyx/Oline_judge/oj_server/questions/
    public:
        Model(){ assert(LoadQuestions(_question_path + "questions_list.txt")); }
        ~Model(){}

        //根据文件路径加载题目
        bool LoadQuestions(const std::string &file_path)
        {

            std::ifstream ifs(file_path);//打开文件
            if(!ifs.is_open()){
                LOG__ERR("open file %s failed",file_path.c_str());
                std::cerr << "Error code: " << strerror(errno) << std::endl;
                return false;
            }
            std::string line;
            while(std::getline(ifs,line)){
                std::vector<std::string> tokens;
                Util_String::SplitStr(line,&tokens," ");
                if(tokens.size()!=5){
                    LOG__ERR("line %s format error size : %ld",line.c_str(),tokens.size());
                    return false;
                }
                Question q;
                q.number = tokens[0];
                q.title = tokens[1];
                q.star = tokens[2];
                q.cpu_limit = std::stoi(tokens[3]);
                q.mem_limit = std::stoi(tokens[4]);

                std::string quest_path = _question_path + q.number + "/";//题目路径

                Util_File::ReadFile(quest_path + "code.cc", &q.code,true);
                Util_File::ReadFile(quest_path + "desc.txt", &q.desc,true);
                Util_File::ReadFile(quest_path + "test.cc", &q.test,true);

                question_map[q.number] = q;
            }

            LOG__INF("load %ld questions sucess",question_map.size());
            ifs.close();
            return true;
            
        }


        bool GetAllQuestions(std::vector<Question> *out)
        {
            if(question_map.empty()){
                LOG__INF("question map is empty");
                return false;
            }

            for(const auto &it : question_map){
                out->push_back(it.second);
            }
            return true;
        }
        bool GetOneQuestion(const std::string number,Question *q)
        {
            auto it = question_map.find(number);
            if(it == question_map.end()){
                LOG__ERR("question %s not found",number.c_str());
                return false;
            }
            *q = it->second;
            return true;
        }

};